/*
 * @Author: cl
 * @Description: 基础变量笔记
 * @Date: 2022-12-06 10:28:17
 * @LastEditTime: 2023-04-24 15:05:17
 * @FilePath: \jsnode\typescript\varTest.ts
 */

// let myString1: string = "我是单引号";
// let myString2: string = "我是双引号";
// let myString3: string = `我是模板字符串${myString2}`;
// console.log(myString1,myString2,myString3)

// let myTuple: [string, number] = ["myNate", 12];
// x = [12,'myNate']

// enum Color {
//   Red = 1,
//   Green = 2,
//   Blue = 4,
// }
// let colorName1: string = Color[0];
// let colorName2: string = Color[1];
// let colorName3: string = Color[2];

// let colorName4: Color = Color.Red;
// let colorName5: Color = Color.Green;
// let colorName6: Color = Color.Blue;

// console.log(
//   colorName1,
//   colorName2,
//   colorName3,
//   colorName4,
//   colorName5,
//   colorName6
// );

// let myAny: any;
// myAny = "myName";
// console.log(myAny)
// myAny = 222;
// console.log(myAny)

// let list: any[] = [1, true, "free"];
// console.log(list)
// list[1] = 100;
// console.log(list)

// interface TestInterface {
//   label: string;
//   name?: string;
// }

// function testIterface(msg: TestInterface) {
//   console.log(msg.label);
//   console.log(msg.name);
// }
// let myMsg = { age: 15, label: "小飞侠", name: "张三" };

// testIterface(myMsg);
// interface StringArray {
//   [index: number]: string;
// }

// let myArray: StringArray;
// myArray = ["Bob", "Fred"];

// let myStr: string = myArray[0];

// console.log(myStr);

// interface Animal {
//   name: string;
//   age: number;
//   setName(name: string): void;
// }

// class Cat implements Animal {
//   name: string;
//   age: number;
//   constructor(n: string, a: number) {
//     this.name = n;
//     this.age = a;
//   }
//   setName(name: string) {
//     this.name = name;
//   }
// }

// let cat: Cat = new Cat("tom", 4);
// console.log(cat)
// cat.setName("small tom");
// console.log(cat)

// let myUnknow: unknown = 222;
// console.log(myUnknow,typeof(myUnknow));
// myUnknow = "李四";
// console.log(myUnknow,typeof(myUnknow));

// let myAdd: (x: number, y: number) => number = function (
//   x: number,
//   y: number
// ): number {
//   return x + y;
// };

// console.log(myAdd(222, 98));

// let myerro: String = "asdasdasd";
// console.log(myerro);
// function reverse(s: String): String {
//   return s.split("").reverse().join("");
// }

// console.log(reverse("hello world"));
// interface SquareConfig {
//   color?: string;
//   width?: number;
//   name: string;
// }

// function createSquare(config: SquareConfig): {
//   color: string;
//   area: number;
//   name: string;
// } {
//   return {
//     color: config.color!,
//     area: config.width! * config.width!,
//     name: config.name,
//   };
// }

// let mySquare = createSquare({
//   colour: "red",
//   width: 100,
//   name: "zhangsan",
// } as SquareConfig);

// let squareOptions = { colour: "red", width: 100 };
// let mySquare = createSquare(squareOptions);
// console.log(mySquare)
// interface testIterface {
//   (name: string, age: number): boolean;
// }

// let testFun: testIterface;
// testFun = function (name: string, age: number): boolean {
//   return false
// };
// testFun = function (name, age) {
//   return false;
// };

// console.log(testFun('222',12))

// interface myArray {
//   [index: number]: string;
// }
// let myArrayList: myArray;
// myArrayList = ["222", "zhanghsan"];

// interface NumberDictionary {
//   [index: string]: number | string;
//   length: number; // 可以，length是number类型
//   name: string; // 错误，`name`的类型与索引类型返回值的类型不匹配
// }
// class Animal {
//   name: string;
// }
// class Dog extends Animal {
//   breed: string;
// }
// interface NotOkay {
//   [x: number]: Animal;
//   [x: string]: Dog;
// }

// interface ClockConstructor {
//   new (hour: number, minute: number);
// }

// class Clock implements ClockConstructor {
//   currentTime: Date;
//   constructor(h: number, m: number) {}
// }

// interface ClockConstructor {
//   new (hour: number, minute: number);
// }

// interface ClockInterface {
//   tick();
// }

// const Clock: ClockConstructor = class Clock implements ClockInterface {
//   constructor(h: number, m: number) {}
//   tick() {
//     console.log("beep beep");
//   }
// };
// class Control {
//   private state: any;
// }

// interface SelectableControl extends Control {
//   select(): void;
// }

// class Button extends Control implements SelectableControl {
//   select() {}
// }

// class TextBox extends Control {
//   select() {}
// }

// class ImageControl extends Control implements SelectableControl {
//   // Error: Class 'ImageControl' incorrectly implements interface 'SelectableControl'.
//   //  Types have separate declarations of a private property 'state'.
//   select() {
//     console.log("lalal   select");
//   }
// }

// let myImC = new ImageControl();

// console.log(myImC.select())

// let aa: string = "zhangsan";
// console.log(aa);
// let bb: any = 111;
// aa = bb;
// console.log(aa);
// console.log(typeof(aa));

// let cc:unknown = '222'
// console.log(cc);
// console.log(typeof(cc));
// bb=cc
// console.log(bb);
// console.log(typeof(bb));

// interface Square {
//   width: number;
//   height: number;
//   readonly name: string;
// }
// class MySquare implements Square {
//   width: number;
//   height: number;
//   name: string;
// }

// function createSquare11(width: number, height: number): MySquare {
//   let mySquare = new MySquare();
//   (mySquare.width = width), (mySquare.height = height);
//   mySquare.name = "陈立";
//   return mySquare;
// }

// let mySquare1 = createSquare11(18, 18);

// function buildName(firstName: string, ...restOfName: string[]) {
//   return firstName + "---" + restOfName.join(" ");
// }

// let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
// console.log(employeeName)

// function rollDice(): 1 | 2 | 3 | 4 | 5 | 6 {
//   return (Math.floor(Math.random() * 6) + 1) as 1 | 2 | 3 | 4 | 5 | 6;
// }

// const result = rollDice();

// class Person {
//   name: string;
//   constructor(name: string) {
//     this.name = name;
//   }
//   say(): string {
//     return 'hello  '+this.name;
//   }
// }

// let person = new Person('张三');
// console.log(person)
// console.log(person.say())

// class ItPerson{
//   protected drink:string
//   love996(){
//       console.log('I love 996')
//   }
// }
// class Dog extends ItPerson{
//   name:string;
//   age:number;
//   eat(){
//       console.log('I love baba')
//   }
// }

// //重新父类方法
// class Cat extends ItPerson{
//   name:string
//   age:number
//   constructor(drinkJiu:string){
//     super()
//     this.drink = drinkJiu
//   }
//   eat(){
//       console.log('I love baba')
//   }
//   love996(){
//     console.log('I not love 996'+this.drink)
//     super.love996()
//   }
// }

// class Fish extends ItPerson{
//   constructor(private name:string){
//     super()
//   }
//   fishjob(){
//     console.log(`${this.name}love摸鱼`)
//   }
// }
// let blackDog = new Dog()
// blackDog.eat()
// blackDog.love996()
// let blackCat = new Cat('987')
// blackCat.eat()
// blackCat.love996()
// let blackFish = new Fish('咸鱼')
// blackFish.love996()
// blackFish.fishjob()
// class MyPerson{
//   static tag = '王连胜'
//   sayTag(){
//       console.log(MyPerson.tag)
//   }
// }
// let xiaoming = new MyPerson();
// xiaoming.sayTag()

// class Greeter {
//   static standardGreeting = "Hello, there";
//   greeting: string;
//   greet() {
//       if (this.greeting) {
//           return "Hello, " + this.greeting;
//       }
//       else {
//           return Greeter.standardGreeting;
//       }
//   }
// }

// let greeter1: Greeter;
// greeter1 = new Greeter();
// console.log(greeter1.greet());

// let greeterMaker: typeof Greeter
// console.log(typeof greeterMaker)
// console.log(typeof Greeter)
// greeterMaker = Greeter;
// greeterMaker.standardGreeting = "Hey there!";

// let greeter2: Greeter = new greeterMaker();
// console.log(greeter2.greet());

// let getMyT = <T>(arg:T):T=>{
//   return arg
// }
// console.log(getMyT<number>(123123))
// console.log(getMyT('wang'))
// function loggingIdentity<T>(arg: Array<T>): Array<T> {
//   console.log(arg.length);  // Array has a .length, so no more error
//   return arg;
// }
// loggingIdentity(['asdasd'])

// interface Todo {
//     title: string;
//     description: string;
// }

// function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
//     return { ...todo, ...fieldsToUpdate };
// }

// const todo1 = {
//     title: 'organize desk',
//     description: 'clear clutter',
// };

// const todo2 = updateTodo(todo1, {
//     description: 'throw out trash',
// });
// console.log(todo2)
// interface PageInfo {
//     title: string;
// }

// type Page = 'home' | 'about' | 'contact';

// const x: Record<Page, PageInfo> = {
//     about: { title: 'about' },
//     contact: { title: 'contact' },
//     home: { title: 'home' },
// };
// console.log(x)

// type T0 = Exclude<'a' | 'b' | 'c', 'a'>; // "b" | "c"
// type T1 = Exclude<'a' | 'b' | 'c', 'a' | 'b'>; // "c"
// type T2 = Exclude<string | number | (() => void), Function>; // string | number

interface Bird {
  fly();
  layEggs();
}

interface Fish {
  swim();
  layEggs();
}

function isFish(pet: Fish | Bird): pet is Fish {
  return (<Fish>pet).swim !== undefined;
}

class MyFish implements Fish {
  swim() {
    console.log("游泳");
  }
  layEggs() {
    throw new Error("Method not implemented.");
  }
}

let myFish = new MyFish();
console.log(isFish(myFish));
myFish = null;
// console.log(myFish!.swim())

function fixed(name: string | null): string {
  function postfix(epithet: string) {
    return name!.charAt(0) + ".  the " + epithet; // ok
  }
  name = name || "Bob";
  return postfix("great");
}
console.log('yom'.charAt(0) );

type Alias = { num: number }
interface Interface {
    num: number;
}
declare function aliased(arg: Alias): Alias;
declare function interfaced(arg: Interface): Interface;

let test1:Alias = {
    num: 0,
}
test1.num = 23
class Test2 implements Interface {
    num: number;
    name:string;
}
let test2 = new Test2();
test2.num = 34
test2.name = 'myname'

/**
 * 
 *  创建类的实例，初始化类的属性,使用constructor来构造函数
 * 
 * 将多个类的功能合并成一个类的过程
 * 先定义接口，使用表达式和接口实现混入
 * 
 * 将不同功能代码区分整理分类，使用namespace 来命名空间，使用
 * 
 * 
 *  */